package com.qingcheng.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.qingcheng.dao.BrandMapper;
import com.qingcheng.dao.SpecMapper;
import com.qingcheng.service.goods.SkuSearchService;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.*;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.aggregations.Aggregation;
import org.elasticsearch.search.aggregations.AggregationBuilders;
import org.elasticsearch.search.aggregations.Aggregations;
import org.elasticsearch.search.aggregations.bucket.terms.Terms;
import org.elasticsearch.search.aggregations.bucket.terms.TermsAggregationBuilder;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class SkuSearchServiceImpl implements SkuSearchService {

    @Autowired
    private RestHighLevelClient restHighLevelClient;

    @Autowired
    private BrandMapper brandMapper;

    @Autowired
    private SpecMapper specMapper;


    public Map search(Map<String, String> searchMap) {
        //封装查询条件(查询请求对象)
        SearchRequest searchRequest = new SearchRequest("sku"); //GET sku/_search
        searchRequest.types("doc");

        //查询源构建器
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();//布尔查询构建器
        //关键字搜索(匹配查询构建器)
        MatchQueryBuilder matchQueryBuilder = QueryBuilders.matchQuery("name", searchMap.get("keywords"));
        boolQueryBuilder.must(matchQueryBuilder);
        //查询的请求中需要添加对分类的查询
        if (searchMap.get("category")!=null){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("categoryName", searchMap.get("categoryName"));
            boolQueryBuilder.filter(termQueryBuilder);
        }
        if (searchMap.get("brand")!=null){
            TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery("brandName", searchMap.get("brand"));
            boolQueryBuilder.filter(termQueryBuilder);
        }
        //1.4 规格过滤
        for(String key: searchMap.keySet() ){
            if( key.startsWith("spec.") ){//如果是规格参数 spec.网络制式
                TermQueryBuilder termQueryBuilder = QueryBuilders.termQuery(key+".keyword", searchMap.get(key));
                boolQueryBuilder.filter(termQueryBuilder);
            }
        }
        //1.5 价格过滤 1-100
        if(searchMap.get("price")!=null ){
            String[] price = searchMap.get("price").split("-");
            if(!price[0].equals("0")){ //最低价格不等于0
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").gte(price[0] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
            if(!price[1].equals("*")){ //如果价格由上限
                RangeQueryBuilder rangeQueryBuilder = QueryBuilders.rangeQuery("price").lte(price[1] + "00");
                boolQueryBuilder.filter(rangeQueryBuilder);
            }
        }
        searchSourceBuilder.query(boolQueryBuilder);

        Integer pageSize = 30;//每页容量
        Integer fromIndex = (Integer.parseInt(searchMap.get("pageNo"))-1)*pageSize;//第几页内容
        //from(60)/size(30)每页显示30条记录，查询第3页内容
        searchSourceBuilder.from(fromIndex); //查询第三页(从第60条数据开始显示)
        searchSourceBuilder.size(pageSize); //每页的容量

        //排序(需要排序字段,排序规则)[销量排序]
        if (!"".equals(searchMap.get("sort"))) {
            String sort = searchMap.get("sort"); //排序字段
            String sortOrder = searchMap.get("sortOrder"); //排序规则
            searchSourceBuilder.sort(sort, SortOrder.valueOf(sortOrder));
        }

        //高亮显示
        HighlightBuilder highlightBuilder = new HighlightBuilder();
        highlightBuilder.field("name").preTags("<font style='color:red'>").postTags("</font>");
        searchSourceBuilder.highlighter(highlightBuilder);
        searchRequest.source(searchSourceBuilder);


        //聚合查询(.terms 自定义分组名 .field需要分组的字段)
        TermsAggregationBuilder termsAggregationBuilder = AggregationBuilders.terms("sku_category").field("categoryName");
        searchSourceBuilder.aggregation(termsAggregationBuilder);


        //封装查询结果
        Map resultMap = new HashMap();
        try {
            SearchResponse searchResponse = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
            //关键词搜索的所有商品获取存储
            SearchHits searchHits = searchResponse.getHits();
            long totalHits = searchHits.getTotalHits(); //记录数
            resultMap.put("totalPage",(totalHits%pageSize==0)?(totalHits/pageSize):(totalHits/pageSize+1));
            System.out.println(totalHits);
            SearchHit[] hits = searchHits.getHits();
            List<Map<String, Object>> resultList = new ArrayList<Map<String, Object>>();
            for (SearchHit hit : hits) {
                Map<String, Object> skuMap = hit.getSourceAsMap();
                //取出高亮处理的信息
                Map<String, HighlightField> highlightFields = hit.getHighlightFields();
                HighlightField highlightField = highlightFields.get("name");
                Text[] fragments = highlightField.fragments();
                String keywords = fragments[0].toString();
                skuMap.put("name",keywords);


                resultList.add(skuMap);

            }
            resultMap.put("rows",resultList);

            //2.2 商品分类列表
            Aggregations aggregations = searchResponse.getAggregations();
            Map<String, Aggregation> aggregationMap = aggregations.getAsMap();
            Terms terms = (Terms) aggregationMap.get("sku_category");

            List<? extends Terms.Bucket> buckets =  terms.getBuckets();
            List<String> categoryList=new ArrayList();
            for( Terms.Bucket bucket:buckets ){
                categoryList.add(bucket.getKeyAsString());
            }
            resultMap.put("categoryList",categoryList);
            //前台如果没有选择品牌,默认显示第一个分类的所有品牌
            String categoryName = "";//商品分类名称
            if (searchMap.get("category") == null) { // 如果没有分类条件
                if (categoryList.size() > 0) {
                    categoryName = categoryList.get(0);//提取分类列表的第一个分类
                }
            } else {
                categoryName = searchMap.get("category");//取出参数中的分类
            }
            //2.3 品牌列表
            if(searchMap.get("brand")==null) {
                List<Map> brandList = brandMapper.findListByCategoryName(categoryName);//查询品牌列表
                resultMap.put("brandList", brandList);
            }

            //2.4 规格列表
            List<Map> specList = specMapper.findListByCategoryName(categoryName);//规格列表
            for(Map spec:specList){
                String[] options = ((String) spec.get("options")).split(",");//规格选项列表
                spec.put("options",options);
            }
            resultMap.put("specList",specList);



        } catch (Exception e) {
            e.printStackTrace();
        }


        return resultMap;
    }
}
